package com.fancy.playlist.controller;

import com.fancy.common.dto.PageResult;
import com.fancy.common.dto.PlaylistBasicInfo;
import com.fancy.common.dto.SongBasicInfo;
import com.fancy.common.dto.response.Result;
import com.fancy.playlist.dto.PlaylistDetailDTO;
import com.fancy.playlist.entity.Playlist;
import com.fancy.playlist.service.PlaylistService;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;

@Api(tags = "播放列表管理")
@RestController
@RequestMapping("/api/v1/playlists")
@RequiredArgsConstructor
public class PlaylistController {

    private final PlaylistService playlistService;

    @ApiOperation(value = "创建播放列表", notes = "用户创建新的播放列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "playlistName", value = "播放列表名称", required = true, paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "description", value = "描述", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "coverUrl", value = "封面URL", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "isPublic", value = "是否公开", paramType = "query", dataType = "boolean", example = "true")
    })
    @PostMapping
    public Result<Long> createPlaylist(
            @RequestParam Long userId,
            @RequestParam String playlistName,
            @RequestParam(required = false) String description,
            @RequestParam(required = false) String coverUrl,
            @RequestParam(defaultValue = "true") Boolean isPublic) {
        Long playlistId = playlistService.createPlaylist(userId, playlistName, description, coverUrl, isPublic);
        if (playlistId != null) {
            return Result.success(playlistId);
        } else {
            return Result.fail("创建播放列表失败");
        }
    }

    @ApiOperation(value = "获取播放列表详情", notes = "根据播放列表ID获取详细信息")
    @ApiImplicitParam(name = "playlistId", value = "播放列表ID", required = true, paramType = "path", dataType = "long")
    @GetMapping("/{playlistId}")
    public Result<PlaylistDetailDTO> getPlaylistDetail(@PathVariable Long playlistId) {
        PlaylistDetailDTO playlist = playlistService.getPlaylistDetailWithUsername(playlistId);
        if (playlist != null) {
            return Result.success(playlist);
        } else {
            return Result.fail("播放列表不存在");
        }
    }

    @ApiOperation(value = "更新播放列表信息", notes = "修改播放列表的基本信息")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "playlistId", value = "播放列表ID", required = true, paramType = "path", dataType = "long"),
        @ApiImplicitParam(name = "playlistName", value = "播放列表名称", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "description", value = "描述", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "coverUrl", value = "封面URL", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "isPublic", value = "是否公开", paramType = "query", dataType = "boolean")
    })
    @PutMapping("/{playlistId}")
    public Result<Void> updatePlaylist(
            @PathVariable Long playlistId,
            @RequestParam(required = false) String playlistName,
            @RequestParam(required = false) String description,
            @RequestParam(required = false) String coverUrl,
            @RequestParam(required = false) Boolean isPublic) {
        boolean success = playlistService.updatePlaylist(playlistId, playlistName, description, coverUrl, isPublic);
        if (success) {
            return Result.success(null);
        } else {
            return Result.fail("更新播放列表失败");
        }
    }

    @ApiOperation(value = "删除播放列表", notes = "删除指定的播放列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "playlistId", value = "播放列表ID", required = true, paramType = "path", dataType = "long"),
        @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "long")
    })
    @DeleteMapping("/{playlistId}")
    public Result<Void> deletePlaylist(@PathVariable("playlistId") Long playlistId, @RequestParam Long userId) {
        boolean success = playlistService.deletePlaylist(playlistId, userId);
        if (success) {
            return Result.success(null);
        } else {
            return Result.fail("删除播放列表失败");
        }
    }

    @ApiOperation(value = "获取用户播放列表", notes = "获取指定用户的所有播放列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "path", dataType = "long"),
        @ApiImplicitParam(name = "page", value = "页码", paramType = "query", dataType = "int", example = "1"),
        @ApiImplicitParam(name = "size", value = "每页大小", paramType = "query", dataType = "int", example = "20")
    })
    @GetMapping("/user/{userId}")
    public Result<PageResult<Playlist>> getUserPlaylists(
            @PathVariable("userId") Long userId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int size) {
        PageResult<Playlist> result = playlistService.getUserPlaylists(userId, page, size);
        return Result.success(result);
    }

    @ApiOperation(value = "添加歌曲到播放列表", notes = "向播放列表中添加歌曲")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "playlistId", value = "播放列表ID", required = true, paramType = "path", dataType = "long"),
        @ApiImplicitParam(name = "songId", value = "歌曲ID", required = true, paramType = "query", dataType = "long")
    })
    @PostMapping("/{playlistId}/songs")
    public Result<Void> addSongToPlaylist(
            @PathVariable("playlistId") Long playlistId,
            @RequestParam Long songId) {
        boolean success = playlistService.addSongToPlaylist(playlistId, songId);
        if (success) {
            return Result.success(null);
        } else {
            return Result.fail("添加歌曲失败，可能歌曲已存在");
        }
    }

    @ApiOperation(value = "从播放列表移除歌曲", notes = "从播放列表中移除指定歌曲")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "playlistId", value = "播放列表ID", required = true, paramType = "path", dataType = "long"),
        @ApiImplicitParam(name = "songId", value = "歌曲ID", required = true, paramType = "path", dataType = "long")
    })
    @DeleteMapping("/{playlistId}/songs/{songId}")
    public Result<Void> removeSongFromPlaylist(
            @PathVariable Long playlistId,
            @PathVariable Long songId) {
        boolean success = playlistService.removeSongFromPlaylist(playlistId, songId);
        if (success) {
            return Result.success(null);
        } else {
            return Result.fail("移除歌曲失败");
        }
    }

    @ApiOperation(value = "获取播放列表歌曲", notes = "获取播放列表中的所有歌曲详细信息")
    @ApiImplicitParam(name = "playlistId", value = "播放列表ID", required = true, paramType = "path", dataType = "long")
    @GetMapping("/{playlistId}/songs")
    public Result<List<SongBasicInfo>> getPlaylistSongs(@PathVariable("playlistId") Long playlistId) {
        List<SongBasicInfo> songs = playlistService.getPlaylistSongsWithDetails(playlistId);
        return Result.success(songs);
    }

    // 内部接口，不显示在API文档中
    @ApiIgnore
    @GetMapping("/internal/{playlistId}")
    public Result<PlaylistBasicInfo> getPlaylistBasicInfo(@PathVariable("playlistId") Long playlistId) {
        PlaylistBasicInfo info = playlistService.getPlaylistBasicInfo(playlistId);
        return Result.success(info);
    }

    @ApiIgnore
    @PostMapping("/internal/batch")
    public Result<List<PlaylistBasicInfo>> getPlaylistBasicInfoBatch(@RequestBody List<Long> playlistIds) {
        List<PlaylistBasicInfo> infos = playlistService.getPlaylistBasicInfoBatch(playlistIds);
        return Result.success(infos);
    }

    @ApiOperation(value = "获取所有公开播放列表标签", notes = "获取所有公开播放列表中使用的标签")
    @GetMapping("/tags")
    public Result<List<String>> getAllPublicPlaylistTags() {
        List<String> tags = playlistService.getAllPublicPlaylistTags();
        return Result.success(tags);
    }

    @ApiOperation(value = "根据标签获取公开播放列表", notes = "根据指定标签获取包含该标签的公开播放列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "tag", value = "标签名称", required = true, paramType = "query", dataType = "string", example = "华语"),
        @ApiImplicitParam(name = "page", value = "页码", paramType = "query", dataType = "int", example = "1"),
        @ApiImplicitParam(name = "size", value = "每页大小", paramType = "query", dataType = "int", example = "20")
    })
    @GetMapping("/by-tag")
    public Result<PageResult<Playlist>> getPublicPlaylistsByTag(
            @RequestParam String tag,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int size) {
        PageResult<Playlist> result = playlistService.getPublicPlaylistsByTag(tag, page, size);
        return Result.success(result);
    }
}
